﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using RacunarskaGrafikaProjekat.source;

namespace RacunarskaGrafikaProjekat {
    public partial class MainForm:Form {
        protected const float distanceStep=15.0f;
        protected const float rotationStep=4f;
        protected bool animationStarted;
        protected int animationTimeline;
        private CWorld m_world;

        public MainForm() {
            InitializeComponent();
            OpenGLControl.InitializeContexts();
            animationStarted=false;
            animationTimeline=0;
            List<String> files=new List<String>();
            files.Add("airplane.3ds");
            List<String> textures=new List<String>();
            textures.Add("asphalt.jpg");
            textures.Add("grass.jpg");
            try {
                m_world=new CWorld("..\\..\\models", files, textures, OpenGLControl.Height, OpenGLControl.Width);
            } catch(Exception e) {
                MessageBox.Show("Neuspesno kreirana instanca OpenGL sveta. Poruka greške: "+e.Message, "GRESKA", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
            }
        }

        private void OpenGLControl_Paint(object sender, PaintEventArgs e) {
            m_world.draw();
        }

        private void OpenGLControl_KeyDown(object sender, KeyEventArgs e) {
            if(animationStarted)
                return;
            switch(e.KeyCode) { 
                case Keys.R:
                    m_world.SceneRotationX-=rotationStep;
                    if(m_world.SceneRotationX<-90)
                        m_world.SceneRotationX=-90;
                    break;
                case Keys.F:
                    m_world.SceneRotationX+=rotationStep;
                    if(m_world.SceneRotationX>0)
                        m_world.SceneRotationX=0;
                    break;
                case Keys.D:
                    m_world.SceneRotationY+=rotationStep;
                    if(m_world.SceneRotationY>360)
                        m_world.SceneRotationY=0;
                    break;
                case Keys.G:
                    m_world.SceneRotationY-=rotationStep;
                    if(m_world.SceneRotationY<-360)
                        m_world.SceneRotationY=0;
                    break;
                case Keys.Add:
                    m_world.SceneDistance+=distanceStep;
                    break;
                case Keys.Subtract:
                    m_world.SceneDistance-=distanceStep;
                    break;
                case Keys.F2:
                    Application.Exit();
                    break;
                case Keys.B:
                    animationStarted=true;
                    animationTimer.Enabled=true;
                    inverseControls();
                    break;
            }

            OpenGLControl.Refresh();
        }

        private void OpenGLControl_Resize(object sender, EventArgs e) {
            m_world.ControlHeight=OpenGLControl.Height;
            m_world.ControlWidth=OpenGLControl.Width;
            m_world.resize();
        }

        private void btnBojaSvetiljki_Click(object sender, EventArgs e) {
            float r=Int32.Parse(tbBojaSvetiljkiR.Text);
            float g=Int32.Parse(tbBojaSvetiljkiG.Text);
            float b=Int32.Parse(tbBojaSvetiljkiB.Text);
            float[] color=new float[3] { r/255, g/255, b/255 };
            m_world.runwayBulbsColor=color;
            OpenGLControl.Refresh();
        }

        private void nudBrojSvetiljki_ValueChanged(object sender, EventArgs e) {
            m_world.runwayBulbs=(int)nudBrojSvetiljki.Value;
            m_world.runwayBulbsIndex=0;
            OpenGLControl.Refresh();
        }

        private void bulbsTimer_Tick(object sender, EventArgs e) {
            m_world.runwayBulbsIndex=(m_world.runwayBulbsIndex+1)%m_world.runwayBulbs;
            OpenGLControl.Refresh();
        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e) {
            bulbsTimer.Interval=50*(11-(int)nudBrzinaPaljenja.Value);
        }

        private void animationTimer_Tick(object sender, EventArgs e) {
            animationTimeline++;
            if(animationTimeline==300) {
                animationTimeline=0;
                inverseControls();
                m_world.initAirplanePosition();
                animationStarted=false;
                animationTimer.Enabled=false;
                return;
            }
            float[] oldPosition=m_world.airplanePosition;
            int step=10*animationTimeline;
            float y=(float)Math.Exp(step/10000);
            float[] newPosition=new float[3] { 0, oldPosition[1]+y/5, 950-step };
            float[] newRotation=new float[3] { (float)Math.Atan(y)*3,0 ,0 };

            m_world.airplanePosition=newPosition;
            m_world.airplaneRotation=newRotation;
        }

        protected void inverseControls(){
            nudBrojSvetiljki.Enabled=!nudBrojSvetiljki.Enabled;
            nudBrzinaPaljenja.Enabled=!nudBrzinaPaljenja.Enabled;
            btnBojaSvetiljki.Enabled=!btnBojaSvetiljki.Enabled;
        }
    }
}
